/**  
* Copyright (c) 2009, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// created by noellynch
// Jun 24, 2009

package com.sceneworker.monitorpopup.panels;

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Callable;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;
import bsh.EvalError;
import bsh.Interpreter;
import bsh.NameSpace;

import com.jme.image.Texture;
import com.jme.scene.Spatial;
import com.jme.scene.state.TextureState;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.TextureManager;
import com.myjavautils.GenericUtils;
import com.myjavautils.swing.MigLayoutUtils;
import com.myjavautils.swing.SimpleAlert;
import com.myjavautils.swing.SimpleImage;
import com.myjavautils.swing.SwingComponentFactory;

public class NewJava2DRenderPanel extends JPanel {

	private		JTextField		mcl_width;
	private		JTextField		mcl_height;
	private		BufferedImage	mcl_image;
	private		SimpleImage		mcl_uiImage;
	private		BeanShellScripter	mcl_scripter;
	
	private		Spatial				mcl_spatial;
	private		TextureState		mcl_ts;
	
	public	NewJava2DRenderPanel(TextureState cl_ts, Spatial cl_s, final JDialog cl_dlg) {
		super();
		
		mcl_ts = cl_ts;
		mcl_spatial = cl_s;
		
		setLayout(new MigLayout("inset 5"));
		
		JPanel		lcl_dimsPanel = MigLayoutUtils.makeStandardPanel();
		mcl_width = MigLayoutUtils.numberText(lcl_dimsPanel, "width", 512, false);
		mcl_height = MigLayoutUtils.numberText(lcl_dimsPanel, "height", 512, false);
		
		JButton		lcl_apply = SwingComponentFactory.makeAButton("Apply");
		lcl_apply.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				initialiseImage();
			}
		});
		lcl_dimsPanel.add(lcl_apply);
		
		add(lcl_dimsPanel, "wrap, width 100%, span, growx");
		
		mcl_scripter = new BeanShellScripter();
		add(mcl_scripter, "width 50%, height 100%");
		
		mcl_uiImage = new SimpleImage();
		add(mcl_uiImage, "wrap, width 50%, height 100%");
		
		JButton		lcl_cancel = SwingComponentFactory.makeAButton("Cancel");
		lcl_cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cl_dlg.setVisible(false);
			}
		});
		
		JButton		lcl_create = SwingComponentFactory.makeAButton("Create");
		lcl_create.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				createTexture(cl_dlg);
			}
		});
		
		MigLayoutUtils.makeRightAlignedButtonBar(this, lcl_cancel, lcl_create);
		
		initialiseImage();
	}
	
	private	void	createTexture(final JDialog cl_par) {
		GameTaskQueueManager.getManager().update(new Callable<Void>() {
			public Void call() throws Exception {
				Texture		lcl_t = TextureManager.loadTexture(mcl_image, Texture.MinificationFilter.Trilinear, 
						Texture.MagnificationFilter.Bilinear, true);

				mcl_ts.setTexture(lcl_t, mcl_ts.getNumberOfSetTextures());
				mcl_ts.setNeedsRefresh(true);
				cl_par.setVisible(false);
				return null;
			}
			
		});
		
	}
	
	private	void	initialiseImage() {
		GraphicsConfiguration		lcl_conf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
		mcl_image = lcl_conf.createCompatibleImage(Integer.parseInt(mcl_width.getText()), Integer.parseInt(mcl_height.getText()), Transparency.TRANSLUCENT);
		mcl_uiImage.setImage(mcl_image);
		repaint();
	}
	
	private	class	BeanShellScripter extends JPanel {
		private		JTextArea		mcl_text;
		private		JTextArea		mcl_err;
		
		public	BeanShellScripter() {
			setLayout(new MigLayout("inset 5"));
			mcl_text = new JTextArea();
			mcl_text.setTabSize(3);
			mcl_text.setText("// the draw method will be called for the image's graphics\n" +
					"// the graphics variable is the associated java 2d graphics of the image\n" +
					"// place your java 2d graphcis commands here"					
					 + "\n\ndraw(graphics, width, height, spatial) {\n}");
			JScrollPane		lcl_scroller = new JScrollPane(mcl_text);
			add(lcl_scroller, "wrap, width 100%, height 75%, span, growx");
			
			mcl_err = new JTextArea();
			JScrollPane		lcl_scroller2 = new JScrollPane(mcl_err);
			add(lcl_scroller2, "wrap, width 100%, height 25%, span, growx");
			
			JButton		lcl_update = SwingComponentFactory.makeAButton("Update");
			lcl_update.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					updateScript();
				}
			});
			add(lcl_update);
			
			JButton		lcl_load = SwingComponentFactory.makeAButton("Load");
			lcl_load.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					File		lcl_file = GenericUtils.getAFile(null, false, false);
					
					if(lcl_file == null) {
						return;
					}
					
					StringBuffer lstr_temp;
					try {
						FileReader		lcl_in = new FileReader(lcl_file);
						BufferedReader	lcl_inB = new BufferedReader(lcl_in);

						lstr_temp = new StringBuffer();
						String			lstr_in = lcl_inB.readLine();

						while(lstr_in != null) {
							lstr_temp.append(lstr_in + "\n");
							lstr_in = lcl_inB.readLine();
						}

						lcl_inB.close();
						
						mcl_text.setText(lstr_temp.toString());
						updateScript();
					} catch (FileNotFoundException e1) {
						SimpleAlert.doAlert("File was not found.", null);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						SimpleAlert.doAlert("IO Error reading file, e = " + e1.getMessage(), null);
					} 
					
				}
			});
			add(lcl_load);
			
			JButton		lcl_save = SwingComponentFactory.makeAButton("Save");
			lcl_save.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e1) {
					File	lcl_f = GenericUtils.getAFile(null, false, true);
					
					if(lcl_f.exists()) {
						return;
					}
					
					try {
						FileWriter		lcl_out = new FileWriter(lcl_f);
						
						lcl_out.write(mcl_text.getText());
						
						lcl_out.flush();
						lcl_out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					return;
				}
			});
			add(lcl_save);
		}
		
		public	void	updateScript() {
			Graphics2D		lcl_g = mcl_image.createGraphics();
			
			try {
				mcl_err.setText("");
				final	Interpreter		mcl_interpreter = new Interpreter();
				Object			lcl_temp = mcl_interpreter.eval(mcl_text.getText());
				final	NameSpace		lcl_nm = mcl_interpreter.getNameSpace();
				
				lcl_nm.invokeMethod("draw", new Object[] { lcl_g, mcl_image.getWidth(), mcl_image.getHeight(), mcl_spatial }, mcl_interpreter);
				
			} catch (EvalError e) {
				// TODO Auto-generated catch block
				mcl_err.setText(e.getMessage());
			}
			
			mcl_uiImage.repaint();
		}
	}
}
